#include "../src/fileControl.hpp"
#include "../src/ProjectConfig.hpp"
#include "../src/Transfer.hpp"
#include <boost/program_options.hpp>
#include <iostream>
#include <signal.h>
#include <regex>
#include <deque>
#include <map>
#include <sstream>

fileControl * file_control;
ProjectConfig * projectConfig;
Transfer * transfer;

namespace po=boost::program_options;

std::string makeListToString(const std::vector<std::string> & list)
{
  if(list.empty()) return "";
  std::stringstream ss;
  for(auto & i : list)
    ss<<i<<',';
  return ss.str();
}

std::string handle_message(std::string msg)
{
  static std::regex word_reg(R"(\S+)");
  std::smatch word_res;
  std::deque<std::string> regex_word;
  while(std::regex_search(msg,word_res,word_reg))
  {
    regex_word.push_back(word_res.str());
    msg=word_res.suffix();
  }
  if(!strcmp(regex_word.at(0).c_str(),"Get"))
  {
    if(!strcmp(regex_word.at(1).c_str(),"Project"))
    {
      if(regex_word.size()==2)
        return makeListToString(projectConfig->GetProjectList());
      else if(!strcmp(regex_word.at(1).c_str(),"Path"))
        return projectConfig->GetProjectPath(regex_word.at(3));
    }
    else if(!strcmp(regex_word.at(1).c_str(),"Task"))
    {
      if(regex_word.size()==3)
        return makeListToString(projectConfig->GetTaskList(regex_word.at(2)));
      else if(!strcmp(regex_word.at(2).c_str(),"Path"))
        return projectConfig->GetTaskPath(regex_word.at(3),regex_word.at(4));
      else if(!strcmp(regex_word.at(2).c_str(),"Video"))
      {
        if(!strcmp(regex_word.at(3).c_str(),"Path"))
          return projectConfig->GetTaskOriginVideoPath(regex_word.at(4),regex_word.at(5),regex_word.at(6));
        else
          return makeListToString(projectConfig->GetTaskOriginVideoList(regex_word.at(3),regex_word.at(4)));
      }
    }
  }
  else if(!strcmp(regex_word.at(0).c_str(),"Create"))
  {
    if(!strcmp(regex_word.at(1).c_str(),"Project"))
    {
      if(regex_word.size()!=4)
        return "False";
      if(file_control->CreateProjectDir(regex_word.at(2)))
      {
        projectConfig->CreateProject(regex_word.at(2),regex_word.at(2),regex_word.at(3));
        return "True";
      }
      else
        return "False";
    }
    else if(!strcmp(regex_word.at(1).c_str(),"Task"))
    {
      if(regex_word.size()==4)
      {
        if(file_control->CreateTaskDir(regex_word.at(2),regex_word.at(3)))
          projectConfig->CreateTask(regex_word.at(2),regex_word.at(3),regex_word.at(3));
        else return "False";
        return "True";
      }
      else if(!strcmp(regex_word.at(2).c_str(),"Video"))
      {
        if(file_control->CheckVideoFile(regex_word.at(3),regex_word.at(4),regex_word.at(6)))
        {
          projectConfig->CreateOriginVideo(regex_word.at(3),regex_word.at(4),regex_word.at(5),regex_word.at(6));
          return "True";
        }
        else return "False";
      }
    }
  }
  return "";
}

void Handle_SIGINT(int)
{
  delete file_control;
  delete projectConfig;
  delete transfer;
  exit(0);
}

int main(int argc,char** argv)
{
  signal(SIGINT,Handle_SIGINT);
  po::options_description desc("options help");
  desc.add_options()
     ("workspace",po::value<std::string>(),"set workspace path");
  po::variables_map vm;
  po::store(po::parse_command_line(argc,argv,desc),vm);
  po::notify(vm);
  if(vm.count("workspace"))
  {
    projectConfig=new ProjectConfig(vm["workspace"].as<std::string>());
    file_control=new fileControl(vm["workspace"].as<std::string>());
  }
  else
  {
    std::cout<<desc<<std::endl;
    return -1;
  }
  transfer=new Transfer(handle_message);
  transfer->run();
}
